]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
altTab: Take over cycle-windows/cycle-group keybindings
authorFlorian Müllner <fmuellner@gnome.org>
Thu, 19 May 2016 12:41:24 +0000 (14:41 +0200)
committerFlorian Müllner <fmuellner@gnome.org>
Thu, 19 May 2016 15:34:00 +0000 (17:34 +0200)
The code to handle cycling through windows without showing a popup
was removed from mutter a while ago, which left the corresponding
keybindings mostly broken (i.e. they now only switch between two
windows). With the various switch-foo keybindings handled by the
shell, it is now easier to take over the cycle-foo keybindings as
well.

https://bugzilla.gnome.org/show_bug.cgi?id=730739

js/ui/altTab.js
js/ui/windowManager.js

index 7029bf75afc6132003b74fb2873e159e3dc70517..cf1174bd12316b0893ef4171863299fedae0657a 100644 (file)
@@ -354,6 +354,59 @@ const AppSwitcherPopup = new Lang.Class({
     }
 });
 
+const CyclerPopup = new Lang.Class({
+    Name: 'CyclerPopup',
+    Extends: SwitcherPopup.SwitcherPopup,
+    Abstract: true,
+
+    _init : function() {
+        this.parent();
+
+        this._items = this._getWindows();
+
+        if (this._items.length == 0)
+            return;
+
+        // We don't show an actual popup, so just provide what SwitcherPopup
+        // expects instead of inheriting from SwitcherList
+        this._switcherList = { actor: new St.Widget(),
+                               highlight: Lang.bind(this, this._highlightItem),
+                               connect: function() {} };
+    },
+
+    _highlightItem: function(index, justOutline) {
+        Main.activateWindow(this._items[index]);
+    },
+
+    _finish: function() {
+        this._highlightItem(this._selectedIndex);
+
+        this.parent();
+    }
+});
+
+
+const GroupCyclerPopup = new Lang.Class({
+    Name: 'GroupCyclerPopup',
+    Extends: CyclerPopup,
+
+    _getWindows: function() {
+        let app = Shell.WindowTracker.get_default().focus_app;
+        return app ? app.get_windows() : [];
+    },
+
+    _keyPressHandler: function(keysym, action) {
+        if (action == Meta.KeyBindingAction.CYCLE_GROUP)
+            this._select(this._next());
+        else if (action == Meta.KeyBindingAction.CYCLE_GROUP_BACKWARD)
+            this._select(this._previous());
+        else
+            return Clutter.EVENT_PROPAGATE;
+
+        return Clutter.EVENT_STOP;
+    }
+});
+
 const WindowSwitcherPopup = new Lang.Class({
     Name: 'WindowSwitcherPopup',
     Extends: SwitcherPopup.SwitcherPopup,
@@ -401,6 +454,32 @@ const WindowSwitcherPopup = new Lang.Class({
     }
 });
 
+const WindowCyclerPopup = new Lang.Class({
+    Name: 'WindowCyclerPopup',
+    Extends: CyclerPopup,
+
+    _init: function() {
+        this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
+        this.parent();
+    },
+
+    _getWindows: function() {
+        let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null;
+        return global.display.get_tab_list(Meta.TabList.NORMAL, workspace);
+    },
+
+    _keyPressHandler: function(keysym, action) {
+        if (action == Meta.KeyBindingAction.CYCLE_WINDOWS)
+            this._select(this._next());
+        else if (action == Meta.KeyBindingAction.CYCLE_WINDOWS_BACKWARD)
+            this._select(this._previous());
+        else
+            return Clutter.EVENT_PROPAGATE;
+
+        return Clutter.EVENT_STOP;
+    }
+});
+
 const AppIcon = new Lang.Class({
     Name: 'AppIcon',
 
index bb54d836c299d11ded11bc48fda9c570e756ca9d..f8aef2dc8332619f97aa2af178054efa39d7dc85 100644 (file)
@@ -866,6 +866,18 @@ const WindowManager = new Lang.Class({
         this.setCustomKeybindingHandler('switch-windows-backward',
                                         Shell.ActionMode.NORMAL,
                                         Lang.bind(this, this._startWindowSwitcher));
+        this.setCustomKeybindingHandler('cycle-windows',
+                                        Shell.ActionMode.NORMAL,
+                                        Lang.bind(this, this._startWindowCycler));
+        this.setCustomKeybindingHandler('cycle-windows-backward',
+                                        Shell.ActionMode.NORMAL,
+                                        Lang.bind(this, this._startWindowCycler));
+        this.setCustomKeybindingHandler('cycle-group',
+                                        Shell.ActionMode.NORMAL,
+                                        Lang.bind(this, this._startGroupCycler));
+        this.setCustomKeybindingHandler('cycle-group-backward',
+                                        Shell.ActionMode.NORMAL,
+                                        Lang.bind(this, this._startGroupCycler));
         this.setCustomKeybindingHandler('switch-panels',
                                         Shell.ActionMode.NORMAL |
                                         Shell.ActionMode.OVERVIEW |
@@ -1766,6 +1778,28 @@ const WindowManager = new Lang.Class({
             tabPopup.destroy();
     },
 
+    _startWindowCycler : function(display, screen, window, binding) {
+        /* prevent a corner case where both popups show up at once */
+        if (this._workspaceSwitcherPopup != null)
+            this._workspaceSwitcherPopup.destroy();
+
+        let tabPopup = new AltTab.WindowCyclerPopup();
+
+        if (!tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask()))
+            tabPopup.destroy();
+    },
+
+    _startGroupCycler : function(display, screen, window, binding) {
+        /* prevent a corner case where both popups show up at once */
+        if (this._workspaceSwitcherPopup != null)
+            this._workspaceSwitcherPopup.destroy();
+
+        let tabPopup = new AltTab.GroupCyclerPopup();
+
+        if (!tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask()))
+            tabPopup.destroy();
+    },
+
     _startA11ySwitcher : function(display, screen, window, binding) {
         Main.ctrlAltTabManager.popup(binding.is_reversed(), binding.get_name(), binding.get_mask());
     },